using System.Threading;
using UnityEngine;

namespace IQIGame.Onigao.Game
{
    public abstract class MessageWrapper
    {
        public delegate void MessageFunction(ISession session, MessageWrapper response);

        protected MessageFunction responseFunction;
        protected ISession session;

        public MessageWrapper() { }

        public void Init(ISession session, MessageFunction responseFunction)
        {
            this.session = session;
            this.responseFunction = responseFunction;
        }

        public abstract int GetMessageId();

        public void Call()
        {
            responseFunction.Invoke(session, this);
        }

        public virtual void Clear()
        {
            responseFunction = null;
            session = null;
        }
    }

    public class MessageWrapper<T> : MessageWrapper where T : struct, IReceiveMessage
    {
        public T message;
        public override int GetMessageId()
        {
            return message.GetMessageId();
        }

        public void FromPackage(ReceivePackage receivePackage)
        {
            message.FromPackage(receivePackage);
        }

        public override void Clear()
        {
            base.Clear();
            message = default(T);
        }

    }

    public static class MessageWrapperPool<T> where T : struct , IReceiveMessage
    {
        private static volatile MessageWrapper<T> _messageWrapper;

        public static MessageWrapper<T> Get()
        {
            MessageWrapper<T> result = Interlocked.Exchange(ref _messageWrapper, null);
            //if(result == null)
            //{
            //    Debug.LogWarning("new MessageWrapper type = " + typeof(T));
            //}
            return result == null ? new MessageWrapper<T>() : result;
        }

        public static void Put(MessageWrapper<T> messageWrapper)
        {
            messageWrapper.Clear();
            _messageWrapper = messageWrapper;
        }
    }

}
